home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
vol6n20.arc
/
STICK.ASM
< prev
next >
Wrap
Assembly Source File
|
1987-10-31
|
21KB
|
469 lines
;STICK.COM for the IBM Personal Computer - 1987 by Jeff Prosise
; [d:][path]STICK [/L+|-] [/E+|-] [/B+|-] [/C-| fg bg]
bios_data segment at 40h
org 60h
bios_cursor dw ? ;cursor mode
org 63h
addr_6845 dw ? ;CRT Controller base address
org 87h
ega_info db ? ;EGA info byte
bios_data ends
;======================================================================
code segment para public 'code'
assume cs:code
org 100h
begin: jmp stick
copyright db "STICK 1.0 (c) 1987 Ziff Communications Co.",13,10,"$",1Ah
author db "Jeff Prosise"
locking db 0FFh ;state of cursor locking
emulation db 0FFh ;state of EGA cursor emulation
foreground db 0FFh ;selected foreground color
background db 0 ;selected background color
cursor_mode dw 0 ;desired cursor definition
adapter db 2 ;0=MDA or CGA, 1=EGA, 2=VGA
old_video label dword
old10h dw 0,0 ;interrupt 10h vector
;-----------------------------------------------------------------------------
;VideoInt intercepts calls to interrupt 10h.
;-----------------------------------------------------------------------------
VideoInt proc near
sti ;enable interrupts
cmp ah,6 ;check for scroll function
jb noscroll
cmp ah,7
ja pass
;
;Check the color selection for screen clear if color locking is on.
;
or al,al ;AL = 0 (clear screen)?
jne pass ;no, then pass thru to BIOS
test cs:[foreground],80h ;color locking active?
jnz pass ;no, then pass thru to BIOS
cmp bh,7 ;white-on-black?
jne pass ;no, then let it go
mov bh,cs:[background] ;reset attribute in BH
push cx
mov cl,4
shl bh,cl
pop cx
or bh,cs:[foreground]
pass: jmp old_video ;pass modified parm to BIOS
;
;See if the cursor mode is to be modified.
;
noscroll: cmp ah,1 ;cursor mode function?
jne pass ;no, then pass to BIOS
test ch,20h ;call to blank the cursor?
jnz pass ;yes, then pass to BIOS
;
;Alter the cursor definition in CX if cursor locking is on.
;
cmp cs:[locking],0FFh ;locking function active?
je nolock ;no, then check emulation function
push ax ;save registers
push cx
push dx
push es
mov cx,cs:[cursor_mode] ;get new cursor value
call SetCursorMode
pop es ;restore registers
pop dx
pop cx
pop ax
iret
;
;See if emulation should be performed.
;
nolock: cmp cs:[emulation],0FFh ;emulation function active?
je pass ;no, then pass control to BIOS
cmp cs:[adapter],1 ;EGA installed?
jne pass ;no, then pass control to BIOS
push ax ;save registers
push es
mov ax,bios_data ;make sure EGA is active
mov es,ax
assume es:bios_data
test es:[ega_info],8
jnz exit ;exit if it's not
test es:[ega_info],1 ;emulation bit set?
jnz exit ;yes, then exit
push bx ;save remaining registers
push cx
push dx
;
;Determine whether or not this call was intended for a CGA.
;
cmp cl,7 ;CGA-type cursor?
ja setmode ;no, then don't alter values
or cl,cl ;EGA ending line?
je setmode ;yes, then don't touch it
;
;Scale the starting and ending scan lines.
;
mov bx,cx ;transfer cursor mode to BX
mov ax,1130h ;determine bytes per character
int 10h ;points in CX
mov al,cl ;transfer points to al
dec al ;determine last scan line
sub al,bl ;calculate adjustment value
or bh,bh ;adjust starting scan line?
je endline ;not if it's zero
add bh,al ;adjust it
endline: add bl,al ;scale ending line
cmp bx,0C0Dh ;normal EGA underline cursor?
jne skip
mov bx,0B0Ch ;yes, then raise it a line
skip: inc bl ;adjust ending line for EGA
cmp bl,cl ;wrap around if necessary
jne nowrap
xor bl,bl
nowrap: or bx,bx ;full height cursor?
jne notfull
mov bl,1Eh ;adjust for full height
notfull: mov cx,bx ;transfer value back to CX
;
;Set the cursor and exit.
;
setmode: call SetCursorMode ;set the cursor
pop dx ;restore registers and exit
pop cx
pop bx
pop es
pop ax
iret
;
;Exit to the BIOS interrupt handling code.
;
exit: pop es ;exit to BIOS
pop ax
jmp cs:old_video
VideoInt endp
;-----------------------------------------------------------------------------
;SetCursorMode sets the cursor to the scan lines indicated in CX.
;-----------------------------------------------------------------------------
SetCursorMode proc near
mov ax,bios_data ;address BIOS data area with ES
mov es,ax
assume es:bios_data
mov es:[bios_cursor],cx ;store cursor mode
mov dx,es:[addr_6845] ;get CRTC address
mov al,10 ;out CH and CL to cursor registers
out dx,al
inc dx
mov al,ch
out dx,al
dec dx
mov al,11
out dx,al
inc dx
mov al,cl
out dx,al
ret
SetCursorMode endp
lastbyte equ $
;-----------------------------------------------------------------------------
;Stick routine receives control when the program is run.
;-----------------------------------------------------------------------------
line1 db 13,10,"Cursor Locking: $"
line2 db "Color Locking: $"
line3 db "Emulation Mode: $"
line4 db "EGA Emulation Bit: $"
errmsg db 13,10,"Usage: [d:][path]STICK [/L+|-] [/E+|-] "
db "[/B+|-] [/C-| fg bg]",13,10,"$"
on db "On",13,10,"$"
off db "Off",13,10,"$"
bitvalue db "0",13,10,"$"
stick proc near
assume cs:code,ds:code,es:code,ss:code
;
;Determine what type of video adapter is installed.
;
mov ax,1A00h ;look for a VGA
int 10h
cmp al,1Ah
jne check_ega ;branch if not found
cmp bl,7 ;make sure it's a VGA
je search
cmp bl,8
je search
check_ega: dec adapter ;check for an EGA
mov ah,12h
mov bl,10h
int 10h
cmp bl,10h
jne search ;branch if EGA is found
dec adapter ;set ADAPTER for CGA or MDA
;
;See if the resident portion of the program is already installed.
;
assume es:nothing
search: cld ;string moves forward
mov word ptr [begin],0 ;zero first two bytes of signature
xor bx,bx ;initialize search segment
mov ax,cs ;record current segment
nextseg: inc bx ;increment search index
mov es,bx
cmp ax,bx ;reached the current segment?
je endloop ;yes, then it's not installed
mov si,offset begin ;look for program signature
mov di,si
mov cx,16
repe cmpsb
jne nextseg ;loop if search failed
;
;Check the command line for entries.
;
endloop: mov si,81h ;point DS:SI to command line
cmp byte ptr [si-1],2 ;any parameters entered?
jb noparms ;no, then branch
call FindParm ;look for a parameter
jnc getparm ;branch if one is found
;
;No parameters were entered. Display current switch settings.
;
noparms: mov ah,9 ;display cursor lock state
mov dx,offset line1
int 21h
mov di,offset locking
call ShowState
mov ah,9 ;display color lock state
mov dx,offset line2
int 21h
mov di,offset foreground
call ShowState
cmp adapter,1 ;EGA installed?
jne terminate ;no, then exit now
mov ah,9 ;display cursor emulation state
mov dx,offset line3
int 21h
mov di,offset emulation
call ShowState
mov ah,9 ;display emulation bit setting
mov dx,offset line4
int 21h
mov ax,bios_data ;address BIOS data area with ES
mov es,ax
test es:[ega_info],1 ;emulation bit set?
jz bitclear ;no, then branch
inc bitvalue ;modify text string
bitclear: mov ah,9
mov dx,offset bitvalue
int 21h
terminate: mov ax,4C00h ;exit with ERRORLEVEL = 0
int 21h
;
;Parse the remainder of the command line for parameters.
;
getparm: cmp al,"/" ;slash character?
jne badparm ;no, then signal error
lodsb ;get current character
and al,0DFh ;capitalize it
cmp al,"L" ;Lock parameter?
jne get1
jmp DoLock
get1: cmp al,"C" ;Color parameter?
jne get2
jmp DoColor
get2: cmp al,"E" ;Emulation parameter?
jne get3
jmp DoEmul
get3: cmp al,"B" ;Bit parameter?
jne badparm ;no, then it's invalid
jmp DoBit
continue: call FindParm ;look for another entry
jnc getparm ;loop back if one is found
;
;Exit and install resident code if it isn't already installed.
;
mov ax,cs ;already installed?
mov bx,es
cmp ax,bx
je install ;no, then install it
mov ax,4C00h ;exit with ERRORLEVEL = 0
int 21h
install: mov ax,3510h ;save and replace int 10h vector
int 21h
mov old10h,bx
mov old10h[2],es
mov ax,2510h
mov dx,offset VideoInt
int 21h
mov ah,9
mov dx,offset copyright
int 21h
mov ax,word ptr ds:[2ch]
mov es,ax
mov ah,49h
int 21h
mov ax,3100h ;terminate-but-stay-resident
mov dx,(offset lastbyte - offset code + 15) shr 4
int 21h
;
;An invalid entry was encountered. Display error message and exit.
;
badparm: mov ah,9 ;print error message
mov dx,offset errmsg
int 21h
mov ax,4C01h ;exit with ERRORLEVEL = 1
int 21h
;-----------------------------------------------------------------------------
;DoLock interprets the command line parameter /L.
;-----------------------------------------------------------------------------
DoLock: lodsb ;get next character
cmp al,"+" ;plus symbol?
jne lock1
mov byte ptr es:[locking],0 ;turn cursor locking on
mov ah,3 ;get cursor mode
int 10h
mov es:[cursor_mode],cx ;store it
jmp short continue ;exit
lock1: cmp al,"-" ;minus symbol?
jne badparm ;no, then it's invalid
mov byte ptr es:[locking],0FFh ;turn cursor locking off
jmp short continue ;exit
;-----------------------------------------------------------------------------
;DoEmul interprets the command line parameter /E.
;-----------------------------------------------------------------------------
DoEmul: lodsb ;get next character
cmp al,"+" ;plus symbol?
jne emul1
mov byte ptr es:[emulation],0 ;turn emulation on
jmp short continue
emul1: cmp al,"-" ;minus symbol?
jne badparm ;no, then it's invalid
mov byte ptr es:[emulation],0FFh ;turn emulation off
jmp continue
;-----------------------------------------------------------------------------
;DoColor interprets the command line parameter /C.
;-----------------------------------------------------------------------------
DoColor: lodsb ;get next character
cmp al,"-" ;minus symbol?
jne color1 ;no, then read hex digits
mov es:[foreground],0FFh ;yes, then toggle color off
jmp continue
color1: call Convert ;get foreground color
jc badparm ;branch on error
mov ah,al ;save it in AH
inc si ;skip space
call Convert ;get background color
jc badparm ;branch on error
cmp al,7 ;attribute in range?
ja badparm ;no, then signal error
mov es:[foreground],ah ;store color values
mov es:[background],al
jmp continue ;exit
;-----------------------------------------------------------------------------
;DoBit interprets the command line parameter /B.
;-----------------------------------------------------------------------------
DoBit: cmp adapter,1 ;is an EGA or VGA installed?
jb bit1 ;no, then ignore the entry
lodsb ;get next character
cmp al,"+" ;plus symbol?
jne bit2
push es ;save ES
mov ax,bios_data ;point ES to BIOS data area
mov es,ax
or es:[ega_info],1 ;set bit 1 of EGA info byte
pop es ;restore ES
bit1: jmp continue
bit2: cmp al,"-" ;minus symbol?
jne reject ;no, then it's invalid
push es ;save ES
mov ax,bios_data ;point ES to BIOS data area
mov es,ax
and es:[ega_info],0FEh ;clear bit 0 of EGA info byte
pop es
jmp continue
reject: jmp badparm ;goto error handler
stick endp
;-----------------------------------------------------------------------------
;FindParm scans the command line for the first non-space character.
;Entry: DS:SI - command line | Exit: CF clear - text found
; | CF set - none found
;-----------------------------------------------------------------------------
FindParm proc near
lodsb ;get next character
cmp al,13 ;end-of-line?
je empty ;yes, then end search
cmp al,32 ;space?
je FindParm ;yes, then continue the scan
clc ;clear CF
ret
empty: stc ;set CF
ret
FindParm endp
;-----------------------------------------------------------------------------
;Convert reads a hex digit and converts it to binary.
;Entry: DS:SI - character | Exit: AL - value
; | CF clear - no error
; | CF set - error
;-----------------------------------------------------------------------------
Convert proc near
lodsb ;skip a character
cmp al,"0" ;less than "0"?
jb conerror
cmp al,"9" ;greater than "9"?
ja alpha
sub al,30h ;convert to binary
clc ;clear CF
ret ;and exit
alpha: and al,0DFh ;capitalize character
cmp al,"A" ;less than "A"?
jb conerror
cmp al,"F" ;greater than "F"?
ja conerror
sub al,37h ;convert to binary
clc
ret
conerror: stc ;set CF
ret
Convert endp
;-----------------------------------------------------------------------------
;ShowState displays the state of the indicated byte (0FFh = "Off")
;Entry: ES:DI - byte value
;-----------------------------------------------------------------------------
ShowState proc near
mov ah,9 ;prepare for output
mov dx,offset off ;assume it's off
cmp byte ptr es:[di],0FFh ;is it really off?
je show1 ;yes, then proceed
mov dx,offset on ;no, then reset string address
show1: int 21h ;print "On" or "Off"
ret
ShowState endp
code ends
end begin